package service

import (
	"context"
	"fmt"
	"gorm.io/gorm"
	"patient-srv/basic/config"

	pb "patient-srv/basic/proto"
	"patient-srv/handler/model"
)

// GetDoctorList 根据关键词分页查询医生列表
// 支持在姓名、职称、擅长领域中模糊匹配
func (s *PatientServiceServer) GetDoctorList(ctx context.Context, req *pb.GetDoctorListRequest) (*pb.GetDoctorListResponse, error) {
	doctor := &model.Doctor{}
	// 调用 Doctor 模型的 ListAll 方法，传入全局数据库连接、关键词、分页参数
	doctors, total, err := doctor.ListAll(config.GlobalDB, req.Keyword, req.Page, req.PageSize)
	if err != nil {
		return &pb.GetDoctorListResponse{
			Message: fmt.Sprintf("查询失败: %v", err),
		}, nil
	}

	// 将 model.Doctor 列表转换为 pb.Doctor 列表
	pbDoctors := toPBDoctors(doctors)
	return &pb.GetDoctorListResponse{
		Total:   total,     // 总记录数，用于前端分页
		Doctors: pbDoctors, // 当前页医生数据
		Message: "success",
	}, nil
}

// GetDoctorsByHospital 根据医院 ID 分页查询该医院下的所有医生
func (s *PatientServiceServer) GetDoctorsByHospital(ctx context.Context, req *pb.GetDoctorsByHospitalRequest) (*pb.GetDoctorsByHospitalResponse, error) {
	doctor := &model.Doctor{}
	doctors, total, err := doctor.ListByHospital(config.GlobalDB, req.HospitalId, req.Page, req.PageSize)
	if err != nil {
		return &pb.GetDoctorsByHospitalResponse{
			Message: fmt.Sprintf("查询失败: %v", err),
		}, nil
	}

	pbDoctors := toPBDoctors(doctors)
	return &pb.GetDoctorsByHospitalResponse{
		Total:   total,
		Doctors: pbDoctors,
		Message: "success",
	}, nil
}

// GetDoctorsByDepartment 根据科室名称分页查询医生
// 注意：此处使用字符串精确匹配科室（如“心血管内科”），非模糊查询
func (s *PatientServiceServer) GetDoctorsByDepartment(ctx context.Context, req *pb.GetDoctorsByDepartmentRequest) (*pb.GetDoctorsByDepartmentResponse, error) {
	doctor := &model.Doctor{}
	doctors, total, err := doctor.ListByDepartment(config.GlobalDB, req.Department, req.Page, req.PageSize)
	if err != nil {
		return &pb.GetDoctorsByDepartmentResponse{
			Message: fmt.Sprintf("查询失败: %v", err),
		}, nil
	}

	pbDoctors := toPBDoctors(doctors)
	return &pb.GetDoctorsByDepartmentResponse{
		Total:   total,
		Doctors: pbDoctors,
		Message: "success",
	}, nil
}

// GetDoctorsByDisease 根据疾病关键词在医生的“擅长领域”中模糊匹配，分页返回结果
// 例如：输入“糖尿病”，可匹配 expertise 包含“糖尿病”的医生
func (s *PatientServiceServer) GetDoctorsByDisease(ctx context.Context, req *pb.GetDoctorsByDiseaseRequest) (*pb.GetDoctorsByDiseaseResponse, error) {
	doctor := &model.Doctor{}
	doctors, total, err := doctor.ListByDisease(config.GlobalDB, req.Disease, req.Page, req.PageSize)
	if err != nil {
		return &pb.GetDoctorsByDiseaseResponse{
			Message: fmt.Sprintf("查询失败: %v", err),
		}, nil
	}

	pbDoctors := toPBDoctors(doctors)
	return &pb.GetDoctorsByDiseaseResponse{
		Total:   total,
		Doctors: pbDoctors,
		Message: "success",
	}, nil
}

// GetDoctorDetail 根据医生 ID 获取医生详细信息
func (s *PatientServiceServer) GetDoctorDetail(ctx context.Context, req *pb.GetDoctorDetailRequest) (*pb.GetDoctorDetailResponse, error) {
	doctor := &model.Doctor{}
	// 调用模型方法根据 ID 查询医生
	if err := doctor.GetByID(config.GlobalDB, req.DoctorId); err != nil {
		// 如果记录不存在，返回友好提示
		if err == gorm.ErrRecordNotFound {
			return &pb.GetDoctorDetailResponse{Message: "医生不存在"}, nil
		}
		// 其他数据库错误
		return &pb.GetDoctorDetailResponse{
			Message: fmt.Sprintf("查询失败: %v", err),
		}, nil
	}

	// 将单个 model.Doctor 转换为 pb.Doctor
	return &pb.GetDoctorDetailResponse{
		Doctor:  toPBDoctor(*doctor),
		Message: "success",
	}, nil
}

// ------------------ 辅助转换函数 ------------------

// toPBDoctor 将内部模型 Doctor 转换为 gRPC 协议定义的 Doctor 消息类型
func toPBDoctor(d model.Doctor) *pb.Doctor {
	return &pb.Doctor{
		Id:                d.ID,
		Name:              d.Name,
		Title:             d.Title,
		Hospital:          d.Hospital,
		HospitalId:        d.HospitalID,
		Department:        d.Department,
		Expertise:         d.Expertise,
		Avatar:            d.Avatar,
		Introduction:      d.Introduction,
		Rating:            d.Rating,
		ConsultationPrice: d.ConsultationPrice,
		IsAvailable:       d.IsAvailable,
		CreatedAt:         d.CreatedAt,
		UpdatedAt:         d.UpdatedAt,
	}
}

// toPBDoctors 批量转换 []model.Doctor 为 []*pb.Doctor
func toPBDoctors(doctors []model.Doctor) []*pb.Doctor {
	pbDoctors := make([]*pb.Doctor, len(doctors))
	for i, d := range doctors {
		pbDoctors[i] = toPBDoctor(d)
	}
	return pbDoctors
}
